package com.cncqs.exception;

import com.cncqs.utils.MyResponseBody;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author: cxy
 * @date: 2019/4/8 0008 下午 4:46
 */
@RestController
@RestControllerAdvice
public class MyGlobalException extends ResponseEntityExceptionHandler implements ErrorController {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * Valid 注解监控
     */
    @Override
    protected ResponseEntity<Object> handleBindException(BindException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        String msg = "绑定对象=[%s]失败[%s][%s]";
        msg = String.format(msg, ex.getObjectName(), ex.getFieldError().getField(), ex.getFieldError().getDefaultMessage());
        return new ResponseEntity(MyResponseBody.failure(msg), HttpStatus.METHOD_NOT_ALLOWED);
    }

    @Override
    protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {
        String msg = "请求失败[%s]";
        msg = String.format(msg, ex.getMessage());
        return new ResponseEntity(MyResponseBody.failure(msg), HttpStatus.BAD_REQUEST);
    }

    /**
     * 全局异常捕获.
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    public MyResponseBody allExceptioenHandler(Exception e) {
        logger.error("操作失败{}", e);
        if (e instanceof MyServiceException) {
            return MyResponseBody.failure(MyResponseBody.CODE_FAILURED, e.getMessage());
        }
        if (e instanceof DuplicateKeyException) {
            return MyResponseBody.failure(MyResponseBody.CODE_FAILURED, "数据重复,请仔细核对");
        }
        return MyResponseBody.failure(MyResponseBody.CODE_FAILURED, "服务器异常,请联系管理员。"+ e.getMessage());
    }

    /**
     * 404异常处理.
     *
     * @return
     */
    @Override
    public String getErrorPath() {
        return "error";
    }

    @RequestMapping(value = "error")
    public Object error(HttpServletResponse response, HttpServletRequest request) {
        String msg = "请核实请求路径是否正确";
        return MyResponseBody.failure(MyResponseBody.CODE_FAILURED, msg);
    }
}
